package com.gitee.wsl.time.chinese.bean.eightchar

import com.gitee.wsl.time.chinese.Lunar
import com.gitee.wsl.time.chinese.Solar
import com.gitee.wsl.time.chinese.bean.EightChar
import com.gitee.wsl.time.chinese.bean.JieQi
import com.gitee.wsl.time.chinese.util.LunarUtil

/**
 * 运
 *
 * @author 6tail
 */
class Yun(
    eightChar: EightChar,
    /**
     * 性别(1男，0女)
     */
    val gender: Int,
    sect: Int
) {
    /**
     * 获取性别
     *
     * @return 性别(1男 ， 0女)
     */

    /**
     * 获取起运年数
     *
     * @return 起运年数
     */
    /**
     * 起运年数
     */
    var startYear: Int = 0
        private set

    /**
     * 获取起运月数
     *
     * @return 起运月数
     */
    /**
     * 起运月数
     */
    var startMonth: Int = 0
        private set

    /**
     * 获取起运天数
     *
     * @return 起运天数
     */
    /**
     * 起运天数
     */
    var startDay: Int = 0
        private set

    /**
     * 获取起运小时数
     *
     * @return 起运小时数
     */
    /**
     * 起运小时数
     */
    var startHour: Int = 0
        private set

    /**
     * 是否顺推
     *
     * @return true/false
     */
    /**
     * 是否顺推
     */
    val isForward: Boolean

    private val lunar: Lunar = eightChar.lunar

    /**
     * 使用默认流派1初始化运
     * @param eightChar 八字
     * @param gender 性别，1男，0女
     */
    constructor(eightChar: EightChar, gender: Int) : this(eightChar, gender, 1)

    /**
     * 初始化运
     * @param eightChar 八字
     * @param gender 性别，1男，0女
     * @param sect 流派，1按天数和时辰数计算，3天1年，1天4个月，1时辰10天；2按分钟数计算
     */
    init {
        // 阳
        val yang = 0 == lunar.yearGanIndexExact % 2
        // 男
        val man = 1 == gender
        this.isForward = (yang && man) || (!yang && !man)
        computeStart(sect)
    }

    /**
     * 起运计算
     */
    private fun computeStart(sect: Int) {
        // 上节
        val prev = lunar.prevJie?:return
        // 下节
        val next = lunar.nextJie?:return
        // 出生日期
        val current = lunar.solar
        // 阳男阴女顺推，阴男阳女逆推
        val start = if (this.isForward) current else prev.solar
        val end = if (this.isForward) next.solar else current

        val year: Int
        var month: Int
        val day: Int
        var hour = 0

        if (2 == sect) {
            var minutes = end.subtractMinute(start)
            val y = minutes / 4320
            minutes -= y * 4320
            val m = minutes / 360
            minutes -= m * 360
            val d = minutes / 12
            minutes -= d * 12
            val h = minutes * 2
            year = y.toInt()
            month = m.toInt()
            day = d.toInt()
            hour = h.toInt()
        } else {
            val endTimeZhiIndex =
                if (end.hour == 23) 11 else LunarUtil.getTimeZhiIndex(end.toYmdHms().substring(11, 16))
            val startTimeZhiIndex =
                if (start.hour == 23) 11 else LunarUtil.getTimeZhiIndex(start.toYmdHms().substring(11, 16))
            // 时辰差
            var hourDiff = endTimeZhiIndex - startTimeZhiIndex
            // 天数差
            var dayDiff: Int = end.subtract(start)
            if (hourDiff < 0) {
                hourDiff += 12
                dayDiff--
            }
            val monthDiff = hourDiff * 10 / 30
            month = dayDiff * 4 + monthDiff
            day = hourDiff * 10 - monthDiff * 30
            year = month / 12
            month -= year * 12
        }
        this.startYear = year
        this.startMonth = month
        this.startDay = day
        this.startHour = hour
    }

    fun getLunar(): Lunar {
        return lunar
    }

    val startSolar: Solar
        /**
         * 获取起运的阳历日期
         *
         * @return 阳历日期
         */
        get() {
            var solar: Solar = lunar.solar
            solar = solar.nextYear(startYear)
            solar = solar.nextMonth(startMonth)
            solar = solar.next(startDay)
            return solar.nextHour(startHour)
        }

    val daYun: Array<DaYun>
        /**
         * 获取10轮大运
         *
         * @return 大运
         */
        get() = getDaYun(10)

    /**
     * 获取大运
     *
     * @param n 轮数
     * @return 大运
     */
    fun getDaYun(n: Int): Array<DaYun> {
        val l = Array<DaYun>(n){i->
            DaYun(this, i)
        }
//        for (i in 0..<n) {
//            l[i] = DaYun(this, i)
//        }
        return l
    }
}

